

from unicodedata import name
from flask import g
from sqlalchemy import and_
from app.libs.forms import CreateResourcePureForm, ResourceByIDForm, GetResourceListForm, SearchForm, UploadByPathForm
from vsearcher import VSearcher
from app.models import chapter
from app.models.chapter import Chapter
from app.models.course import Course
from app.service.video import VideoService
from vsearcher._core import vo as vs_vo
from app.vo import SChapterVO
from .base import BaseService
class ChapterService(BaseService):
    """
        功能：
        1. 获取目录结构
        2. 获取不带视频信息
    """

    @classmethod
    def get_by_id(cls, form: ResourceByIDForm) -> Chapter:
        chapter_id = form.data.get('id')
        return cls.optional_404(Chapter.current_user_filter(Chapter.id == chapter_id).first())

    @classmethod
    def create_pure(cls, form: CreateResourcePureForm) -> Chapter:
        with Chapter.auto_commit() as context:
            chapter_name = form.name.data
            # 记录重名的解决方案，@WAIT 可以尝试编写 数据库的触发器和函数，处理更佳
            count = Chapter.current_user_filter(
                and_(Chapter.name.like(f'{chapter_name}%'),
                Chapter.course_id == form.course_id.data )
                ).count()
            if count > 0:
                chapter_name = f'{chapter_name}_{count}'


            def getCourseName() -> str:
                """ 获取所属课程的课程名称, 用于生成章节输出路径 """
                if form.course_id.data:
                    return cls.optional_404(
                        Course.query.get(form.course_id.data)
                    ).name
                return ""

            new_chapter = Chapter(
                name=chapter_name,
                user_id=g.current_user.id,
                course_id=form.course_id.data,
                output_dir = VSearcher.createChapterDir(
                    chapter_name=chapter_name,
                    course_name= getCourseName()
                 )
                )
            context.session.add(new_chapter)
        return new_chapter


    @classmethod
    def save2db(cls, vs_chapter_vo: vs_vo.ChapterVO, course_id=None):
        new_chapter =  Chapter().set_attr(vs_chapter_vo, filter_keys=['id','videos']) # 创建章节model
        new_chapter.course_id = course_id
       
        new_chapter.user_id = g.current_user.id
        Chapter.session.add(new_chapter) 
        Chapter.session.flush()# 提交之后得到chapter_id
            # 视频存储到数据库

        for vs_chapter_vo in vs_chapter_vo.videos:
            VideoService.save2db(vs_chapter_vo, chapter_id=new_chapter.id, course_id=course_id)
        return new_chapter

    @classmethod
    def upload_by_path(cls, form: UploadByPathForm):
        # 需要递归的创建记录到数据库中, 
        # 需要视频的文件路径
        with Chapter.auto_commit():
            vs_chapter_vo = VSearcher.executeChapter(form.path.data,
             step=form.vsConfigForm.step.data, 
            speed_x=form.vsConfigForm.speed.data
            ) # 处理章节
            return cls.save2db(vs_chapter_vo)
    
    @classmethod
    def searchByForm(cls, form: SearchForm) -> SChapterVO:
        chapter = cls.optional_404(
            Chapter.current_user_filter(Chapter.id == form.id.data).first()
        )
        return cls.search(form.key.data, chapter)
    
    @classmethod
    def search(cls, key, chapter: Chapter) -> SChapterVO:
        videos_search_result = []
        for video in chapter.videos:
            vs_video_search_result = VideoService.search(key, video)
            if vs_video_search_result.kfs:
                videos_search_result.append(vs_video_search_result)
        s_chapter_vo =  SChapterVO(chapter)
        s_chapter_vo.videos = videos_search_result
        return s_chapter_vo

    @classmethod
    def del_by_id(cls, form: ResourceByIDForm):
        # @RISK 如果一个视频属于某个Chapter 或者 Source 还要更新pickle对象中的内容, 比如删除了某一个上街
        # @WAIT vsearch 支持, 删除某个课程中的某个内容
        chapter = cls.optional_404(Chapter.current_user_filter(
            Chapter.id == form.id.data).first())
        # 需要先删除视频 -》 章节
        with Chapter.auto_commit() as context:
            for video in chapter.videos:
                context.session.delete(video)
            context.session.delete(chapter)
            VSearcher.releaseByOutputDir(chapter.output_dir)  # 删除对象的处理结果： 包括：图片
            return chapter


    @classmethod
    def gets(cls, form: GetResourceListForm):
        return Chapter.current_user_filter(Chapter.course_id == None).offset(form.pager.offset).limit(form.pager.limit).all(), form.pager



 